package com.winsdom.utils;

import com.googlecode.aviator.AviatorEvaluator;

import java.util.*;

public class PriceCalculator {
    // 中文 -> 英文变量映射
    // 保证 VAR_MAP 按顺序排列
    private static final List<String> CHINESE_VAR_ORDER = List.of(
            "当前读数",         // index 0 → key "1"
            "上期读数",         // index 1 → key "2"
            "单价",             // index 2 → key "3"
            "房屋建筑面积",     // index 3 → key "4"
            "房屋配置容量值",   // index 4 → key "5"
            "房屋套内面积",// index 5 → key "6"
            "倍率"

    );

    private static final Map<String, String> VAR_MAP = Map.of(
            "当前读数", "current",
            "上期读数", "previous",
            "单价", "price",
            "房屋建筑面积", "area",
            "房屋配置容量值", "config",
            "房屋套内面积", "innerArea",
            "倍率","magnification"
    );

    /**
     * @param expression 中文公式，例如 “房屋建筑面积 * 单价 + 房屋配置容量值 * 单价”
     * @param amounts 金额列表 Map（key/value 可随便填，value 顺序取用）
     */
    public static double calculate(String expression, Map<String, Object> amounts) {
        // 1. 提取用到的中文变量（按顺序）
        List<String> usedChineseVars = extractChineseVarsInOrder(expression);

        // 2. 从金额 Map 中按顺序取 value
        Iterator<Object> valueIterator = amounts.values().iterator();

        // 3. 构建 Aviator 参数 map
        Map<String, Object> aviatorVars = new HashMap<>();
        Set<String> assigned = new HashSet<>();
        for (String chineseVar : usedChineseVars) {
            if (assigned.contains(chineseVar)) continue;
            assigned.add(chineseVar);
            String englishVar = VAR_MAP.get(chineseVar);
            if (englishVar != null) {
                // 查找在 CHINESE_VAR_ORDER 中的 index → 1-based key
                int index = CHINESE_VAR_ORDER.indexOf(chineseVar);
                String amountKey = String.valueOf(index + 1);
                Object value = amounts.getOrDefault(amountKey, 0.0);
                aviatorVars.put(englishVar, value != null ? value : 0.0);
            }
        }

        // 4. 替换表达式变量为 Aviator 英文名
        String expr = normalize(expression);

        // 5. 执行表达式
        Object result = AviatorEvaluator.execute(expr, aviatorVars);
        return Double.parseDouble(result.toString());
    }

    // 替换为英文变量名
    private static String normalize(String expression) {
        String expr = expression;
        for (Map.Entry<String, String> entry : VAR_MAP.entrySet()) {
            expr = expr.replace(entry.getKey(), entry.getValue());
        }
        return expr.replace("%", "/100.0");
    }

    // 按在表达式中出现顺序提取变量（最长匹配）
    private static List<String> extractChineseVarsInOrder(String expression) {
        List<String> ordered = new ArrayList<>();
        List<String> keys = new ArrayList<>(VAR_MAP.keySet());
        keys.sort((a, b) -> b.length() - a.length()); // 按长度降序避免"房屋"匹配到"房屋建筑面积"
        String expr = expression;

        while (!expr.isEmpty()) {
            boolean matched = false;
            for (String key : keys) {
                if (expr.startsWith(key)) {
                    ordered.add(key);
                    expr = expr.substring(key.length());
                    matched = true;
                    break;
                }
            }
            if (!matched) {
                expr = expr.substring(1); // 跳过无关字符
            }
        }
        return ordered;
    }

    public static void main(String[] args) {
//        String formula = "房屋建筑面积 * 0.04375 * 单价 + 房屋配置容量值 * 单价";
//        String formula = " (当前读数 - 上期读数) * (1 + 1%) * 单价";
//        String formula = "房屋建筑面积*单价+10";
        String formula = "(当前读数 - 上期读数) * (1 + 1%) * 单价 * 倍率";
        // 金额按顺序提供即可，不需要变量名
        Map<String, Object> amounts = Map.of(
                "1", 120,
                "2", 100,
                "3",0.85,
                "4", 120,
                "5", 100,
                "6",80,
                "7",2
        );

        double price = calculate(formula, amounts);
        System.out.println("计算价格：" + price);
    }
}
